<?php
/** 
 * EGP Framework
 *
 * LICENSE
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @author     Akon(番茄红了) <aultoale@gmail.com>
 * @copyright  Copyright (c) 2008 (http://www.tblog.com.cn)
 * @license    http://www.gnu.org/licenses/gpl.html     GPL 3
 */

!defined('EGP_LIB_DIR') && die('Access Deny!');

/**
 * 垃圾信息过滤
 *
 * @package    classes
 * @author     Akon(番茄红了) <aultoale@gmail.com>
 * @copyright  Copyright (c) 2008 (http://www.tblog.com.cn)
 * @license    http://www.gnu.org/licenses/gpl.html     GPL 3
 */
class EGP_Spam
{

    /**
     * 被过滤的 IP 地址
     *
     * @var array
     */
    protected $_ipAddress = array();

    /**
     * 被过滤的词语
     *
     * @var array
     */
    protected $_words = array();

    /**
     * 过滤的正则表达式
     *
     * @var string
     */
    protected $_regex = array();

    /**
     * 添加被过滤的 IP 地址
     *
     * @example  202.65.15*.*, 202.65.*.*, ...
     *
     * @param  string|array  $ipAddress
     * @return EGP_Spam
     * @throws EGP_Exception
     */
    public function addIp($ipAddress)
    {
        if (!is_array($ipAddress)) {
            $ipAddress = array($ipAddress);
        }

        foreach ($ipAddress as $ip) {
            if (preg_match('/^([\d\*]{1,3}\.){3}[\d\*]{1,3}$/', $ip)) {
                $tmp1 = str_replace('*', '1', $ip);
                $tmp2 = ip2long($tmp1);
                if ($tmp2 != -1 && $tmp2 !== false) {
                    continue;
                }
            }
            throw new EGP_Exception("无效的过滤 IP 地址 '$ip'");
        }

        $this->_ipAddress = array_merge($this->_ipAddress, $ipAddress);

        return $this;
    }

    /**
     * 添加被过滤的词语
     *
     * @param  string|array  $word
     * @return EGP_Spam
     */
    public function addWord($word)
    {
        if (!is_array($word)) {
            $word = array($word);
        }

        $this->_words = array_merge($this->_words, $word);

        return $this;
    }

    /**
     * 添加过滤的正则表达式 ( PERL 格式 )
     *
     * @param  string|array  $regex
     * @return EGP_Spam
     */
    public function addRegex($regex)
    {
        if (!is_array($regex)) {
            $regex = array($regex);
        }

        $this->_regex = array_merge($this->_regex, $regex);

        return $this;
    }

    /**
     * 对内容进行过滤判断
     *
     * @param  string|array  $text
     * @return EGP_Spam
     * @throws EGP_Exception
     */
    public function filterText($text)
    {
        if (!is_array($text)) {
            $text = array($text);
        }
        $text = implode("\n", $text);

        //过滤词语
        foreach ($this->_words as $word) {
            if (stripos($text, $word) !== false) {
                throw new EGP_Exception("发现被过滤的词语 '$word'");
            }
        }

        //按正则过滤
        foreach ($this->_regex as $regex) {
            if (preg_match($regex, $text, $m)) {
                throw new EGP_Exception("发现被过滤的内容 '$m[0]'");
            }
        }

        return $this;
    }

    /**
     * 对 IP 地址进行过滤判断
     *
     * @param  string|array  $text
     * @param  string|array  $ipAddress
     * @return EGP_Spam
     * @throws EGP_Exception
     */
    public function filterIp($ipAddress)
    {
        if (!is_array($ipAddress)) {
            $ip = array($ipAddress);
        }
        $ipAddress = implode(" ", $ipAddress);

        foreach ($this->_ipAddress as $ip) {
            $regex = str_replace(array('*', '.'), array('\d{1,3}', '\.'), $ip);
            if (preg_match("/$regex/", $ipAddress)) {
                throw new Exception("发现被过滤的 IP 地址 '$ip'");
            }
        }

        return $this;
    }

    /**
     * 对非法内容进行替换
     *
     * @param  mixed   $text
     * @param  string  $target
     * @return mixed
     */
    public function replace($text, $target = '*')
    {
        if (is_array($text)) {
            $result = array();
            foreach ($text as $t) {
                $result[] = $this->replace($text, $target);
            }

            return $result;
        } else {
            foreach ($this->_words as $word) {
                if (stripos($text, $word) !== false) {
                    $replacement = implode('', array_fill(0, iconv_strlen($word, 'UTF-8'), $target));
                    $text = str_ireplace($word, $replacement, $text);
                }
            }
            foreach ($this->_regex as $regex) {
                if (preg_match($regex, $text)) {
                    $replacement = implode('', array_fill(0, iconv_strlen($regex, 'UTF-8') - 2, $target));
                    $text = preg_replace($regex, $replacement, $text);
                }
            }
            return $text;
        }
    }

}